package com.iot08.api.service;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.tea.utils.StringUtils;
import com.iot08.api.config.redis.RedisClusterService;
import com.iot08.api.response.CmsgResp;
import com.iot08.api.service.supplement.KafkaService;
import com.iot08.api.vo.request.CmsgReqBodyFormVO;
import com.iot08.api.vo.request.CmsgReqVO;
import com.iot08.api.vo.request.InquirePhoneChargeCmsgReqBodyFormVo;
import com.iot08.api.vo.request.InquirePhoneChargeCmsgReqVo;
import com.iot08.common.config.mongodb.query.UpdateVO;
import com.iot08.common.constant.ConstCacheField;
import com.iot08.common.constant.ConstKafka;
import com.iot08.common.entity.app.Account;
import com.iot08.common.entity.app.DeviceCmsg;
import com.iot08.common.service.base.BaseService;
import com.iot08.common.utils.DateUtil;
import com.iot08.common.utils.response.ResponseEnum;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.bson.types.ObjectId;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @version 1.0
 * @Description:
 * @author: Rock
 * @time: 2021/1/8 16:24
 */
@Slf4j
@Service
public class DeviceCmsgService extends BaseService<DeviceCmsg> {

    @Resource
    private AccountService accountService;

    @Resource
    @Lazy
    private DeviceService deviceService;

    @Resource
    private KafkaService kafkaService;

    @Resource
    private RedisClusterService redisClusterService;

    /**
     * 生成代收消息记录
     * @param imei
     * @param tcpCMDData tcp 上传上来的消息
     * @time: 12/13/21 5:22 PM
     * @author: Weichao
     * @version 1.0
     */
    public DeviceCmsg add(String imei, JSONObject tcpCMDData,Integer isInquireCharge) {
        DeviceCmsg cmsg = new DeviceCmsg();
        //来源电话号码
        cmsg.setFromPhone(tcpCMDData.getString("fromPhone"));
        // 在TCP端已做好解码了, 传输过来时候直接赋值即可
        cmsg.setContent(tcpCMDData.getString("content"));
        cmsg.setImei(imei);
        cmsg.setIsInquireCharge(isInquireCharge);
        //时间戳保存到秒
        cmsg.setTime(tcpCMDData.getLong("msgTimestamp"));
        cmsg.setDateTime(DateUtil.timestampToStr(tcpCMDData.getLong("msgTimestamp")*1000,DateUtil.FORMAT_1));
        cmsg.setExpiryAt(DateUtil.getSystemExpiryAt());
        return this.save(cmsg);
    }
    /**
     * 获取代收消息
     * @param imei
     * @param bindTime
     * @param page 当前页
     * @param num 分页查询的 个数
     * @time: 12/13/21 5:34 PM
     * @author: Weichao
     * @version 1.0
     */
    public List<DeviceCmsg> listData(String imei, Double bindTime, Integer dateType, int page ,int num) {
        long startTime;
        long endTime = System.currentTimeMillis()/1000;
        try {
            if(dateType == 1){
                startTime = endTime-7*24*60*60;
            }else if(dateType == 2){
                startTime = endTime -30*24*60*60;
            }else {
                startTime = endTime -3*30*24*60*60;
            }
            if(endTime <= bindTime ){
                // delTime 此时间之前的不查询,返回空
                return new ArrayList<>();
            }
        }catch (Exception e){
            log.error("获取应用使用记录 时间处理 错误:"+e.getMessage(), e);
            return new ArrayList<>();
        }
        //查询用户开始绑定设备后，设备接收到的短信信息，绑定之前的信息不让其看见
        Criteria criteria = Criteria.where("imei").is(imei);
        // imei 且 大于等于(gte) 删除时间的
        //指定日期
        if(bindTime > startTime){
            startTime = bindTime.longValue();
        }
        criteria.and("time").gte(startTime).lte(endTime);
        // imei 且 大于等于(gte) 删除时间的
        Query query = new Query(criteria);
        // 排序, 分页
        return this.find(query.with(Sort.by(Sort.Order.desc("time"))).skip((long) page *num).limit(num));
    }


    /**
     * @description 分页查询代收短信数据
     * @author cwj
     * @param [imei, bindTime, dateType, page, num, res]
     * @return void
     * @date @time 2024/12/23 9:50
     **/
    public void  queryCmsgData(String imei, Double bindTime, Integer dateType, int page ,int num,ResponseMap res,Integer isInquireCharge){
        long total = 0;
        long startTime;
        long endTime = System.currentTimeMillis()/1000;
        res.put("total",total);
        try {
            if(dateType == 1){
                startTime = endTime-7*24*60*60;
            }else if(dateType == 2){
                startTime = endTime -30*24*60*60;
            }else {
                startTime = endTime -3*30*24*60*60;
            }
            if(endTime <= bindTime ){
                // delTime 此时间之前的不查询,返回空
                return;
            }
        }catch (Exception e){
            log.error("获取应用使用记录 时间处理 错误:"+e.getMessage(), e);
            return;
        }
        //查询用户开始绑定设备后，设备接收到的短信信息，绑定之前的信息不让其看见
        Criteria criteria = Criteria.where("imei").is(imei);
        if(ObjectUtils.isNotEmpty(isInquireCharge)) {
            criteria.and("isInquireCharge").is(isInquireCharge);
        }
        // imei 且 大于等于(gte) 删除时间的
        //指定日期
        if(bindTime > startTime){
            startTime = bindTime.longValue();
        }
        criteria.and("time").gte(startTime).lte(endTime);
        // imei 且 大于等于(gte) 删除时间的
        Query query = new Query(criteria);
        //查询分页总数
        total = mongoTemplate.count(query,"device_cmsg");
        //排序分页
        List<CmsgResp> cmsgResps = mongoTemplate.find(query.with(Sort.by(Sort.Order.desc("time"))).skip((long) page *num).limit(num), CmsgResp.class,"device_cmsg");
        res.put("total",total);
        res.put("msgList",cmsgResps);
    }




    /**
     * 删除对应Id的代收短信消息
     * @param delIds
     * @time: 12/14/21 9:38 AM
     * @author: Weichao
     * @version 1.0
     */
    public void delCmsgWithIds(String delIds) {
        //JSONArray idArr = JSON.parseArray(delIds);
        String[] idArr = delIds.split(",");
        //删除指定id
        Set<ObjectId> objectIdList = new HashSet<>();
        for (int i = 0; i < idArr.length; i++) {
            if (ObjectId.isValid(idArr[i])) {
                objectIdList.add(new ObjectId(idArr[i]));
            }
        }
        if (objectIdList.size() > 0) {
            this.delByIds(objectIdList);
        }
    }

    /**
     * 根据imei 号清空对应的记录
     * @param imei
     * @time: 12/15/21 6:13 PM
     * @author: Weichao
     * @version 1.0
     */
    public void delCmsgWithImei(String imei) {
        this.delByQuery(new Query(Criteria.where("i").is(imei)));
    }

    /**
     * 查/改/删代收短信
     * @param imei
     * @param vo
     * @time: 12/13/21 4:08 PM
     * @author: Weichao
     * @version 1.0
     */
    public ResponseMap cmsg(CmsgReqBodyFormVO vo) {
        String imei = vo.getImei();
        ResponseMap res = ResponseMap.success();
        if(vo.getOption().equals("get")){
            if(ObjectUtils.isEmpty(vo.getPage())){
                vo.setPage(0);
            }
            if(ObjectUtils.isEmpty(vo.getNum())){
                vo.setNum(20);
            }
            //检查查询类型有没有传
            if(ObjectUtils.isEmpty(vo.getDateType())){
                //默认查一周的
                vo.setDateType(1);
            }
            //查
            Account account = accountService.findById(vo.getOpenid());
            Map<String, Object> devBingV = account.getDeviceMap().get(imei);
            //该账号绑定此设备的时间
            Double bindTime = new Double(devBingV.get("t").toString());
            Integer page = vo.getPage();
            Integer num = vo.getNum();
            //用什么就查什么，省内存
            Integer cmsgStatus = deviceService.queryCmsgStatusByImei(imei);
            res.put("cmsgStatus", cmsgStatus);
            //查询上报的代收短信信息,并将查询数据置于res中
            queryCmsgData(imei, bindTime, vo.getDateType(), page, num,res,null);
            /* List<DeviceCmsg> deviceCmsgs = this.lisData(imei, bindTime, vo.getDateType(), page, num);
            List<Object> msgList = new ArrayList<>();
            for (DeviceCmsg item: deviceCmsgs) {
                JSONObject temp = new JSONObject();
                temp.put("id",item.getId());
                temp.put("content",item.getContent());
                temp.put("time", DateUtil.timestampToStr(item.getTime()*1000,DateUtil.FORMAT_1));
                temp.put("fromPhone",item.getFromPhone());
                msgList.add(temp);
            }
            res.put("msgList", msgList);*/
        }else if (vo.getOption().equals("change")){
            //检查设备是否在线，不在线不能下发
            String onlineStatus = redisClusterService.hget(imei, ConstCacheField.ONLINE_STATUS);
            if (!"1".equals(onlineStatus)) {
                return ResponseMap.fail(ResponseEnum.STATUS5001.getCode(), ResponseEnum.STATUS5001.getMsg());
            }
            //更新设备的cmsgStatus状态，无需多查一次
            UpdateVO updateVO = new UpdateVO();
            updateVO.set("cmsgStatus", vo.getCmsgStatus());
            deviceService.updateById(imei, updateVO);
            // 下发修改代收短信开关的 指令
            JSONObject kafkaJson = new JSONObject();
            kafkaJson.put("cmsgStatus", vo.getCmsgStatus());
            kafkaService.emitDeviceDemand(imei, ConstKafka.DEV_MESSAGE_SWITCH, kafkaJson,vo.getOpenid());
        }else if (vo.getOption().equals("del")){
            if(StringUtils.isEmpty(vo.getDelIds())){
                //返回请求参数不对的异常
                return ResponseMap.fail(ResponseEnum.STATUS400.getCode(), ResponseEnum.STATUS400.getMsg());
            }
            //删出代收短信
            this.delCmsgWithIds(vo.getDelIds());
        }
        return res;
    }


    /**
     * @description 查询话费流量的短信内容
     * @author cwj
     * @param [vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/3/29 18:17
     **/
    public ResponseMap queryPhoneChargeCmsg(InquirePhoneChargeCmsgReqBodyFormVo vo){
        ResponseMap res = ResponseMap.success();
        //检查查询类型有没有传
        if(ObjectUtils.isEmpty(vo.getDateType())){
            //默认查一周的
            vo.setDateType(1);
        }
        //查询用户信息
        Account account = accountService.findById(vo.getOpenid());
        Map<String, Object> devBingV = account.getDeviceMap().get(vo.getImei());
        //该账号绑定此设备的时间
        Double bindTime = new Double(devBingV.get("t").toString());
        Integer page = vo.getPage();
        Integer num = vo.getNum();
        //用什么就查什么，省内存
        //Integer cmsgStatus = deviceService.queryCmsgStatusByImei(vo.getImei());
        //res.put("cmsgStatus", cmsgStatus);
        //查询上报的代收短信信息,并将查询数据置于res中
        queryCmsgData(vo.getImei(), bindTime, vo.getDateType(), page, num,res,1);
        return res;
    }

    /**
     * @description 清除设备短信记录
     * @author cwj
     * @param [imei]
     * @return void
     * @date @time 2025/6/24 11:46
     **/
    public void delByImei(String imei){
        Query query = new Query(Criteria.where("imei").is(imei));
        mongoTemplate.remove(query,DeviceCmsg.class);
    }
}
